﻿using Koala.Pro.CodeGenerator.UI.DatabaseModel.Schema;
using Koala.Pro.CodeGenerator.UI.Models;

namespace Koala.Pro.CodeGenerator.UI.Common.Adapter
{
    public class EntityAdapter : BaseAdapter
    {
        private const string SUFFIX_OF_PO_CLASS = "Info";

        public EntityAdapter(DatabaseInfo database, List<string> selectedTableNames, string templateFile)
            : base(database, selectedTableNames, templateFile)
        {
            DirectoryOfOutput = setting.ProjectNameList.Entity;
        }

        public override void Execute()
        {
            foreach (var value in database.TableList.Values)
            {
                if (!value.IsMiddleTable && selectedTableNames.Contains(value.Name.Name.ToString()))
                {
                    string message = string.Format("Create the entity files of the table:{0}", value.Name.Name);
                    log.Debug(message);
                    PrepareHeader(value);
                    PrepareFieldAndProperty(value);
                    var tableName = value.Name.Alias.ToCapit();
                    var className = StringFormatter.ToPascalCase(tableName) + SUFFIX_OF_PO_CLASS;
                    FileNameOfOutput = className;
                    OutputFile();
                }
            }
        }

        public override List<FileNameAndCode> ExecuteString()
        {
            List<FileNameAndCode> list = new List<FileNameAndCode>();
            foreach (var value in database.TableList.Values)
            {
                var fileNameAndCode = new FileNameAndCode();
                if (selectedTableNames.Contains(value.Name.Name.ToString()))
                {
                    var tableName = value.Name.Name.ToString();
                    log.Debug($"Create the entity files of the table:{tableName}");
                    PrepareHeader(value);
                    PrepareFieldAndProperty(value);
                    var className = StringFormatter.ToPascalCase(tableName) + SUFFIX_OF_PO_CLASS;
                    FileNameOfOutput = className;
                    fileNameAndCode.FileName = FileNameOfOutput + FileExtension;
                    fileNameAndCode.Code = OutputString();
                    list.Add(fileNameAndCode);
                }
            }
            return list;
        }

        private void PrepareHeader(TableInfo tableInfo)
        {
            var name = tableInfo.Name.Alias.ToCapit();
            var className = StringFormatter.ToPascalCase(name) + SUFFIX_OF_PO_CLASS;
            context.Put("TableInfo", tableInfo);
            context.Put("ClassName", className);
        }

        private void PrepareFieldAndProperty(TableInfo tableInfo)
        {
            List<EntityProperty> value_Renamed = new List<EntityProperty>();
            List<EntityProperty> list = new List<EntityProperty>();
            foreach (ColumnInfo value in tableInfo.ColumnList.Values)
            {
                EntityProperty entityProperty = new EntityProperty();
                entityProperty.NetType = value.NetType.Alias.ToString();
                entityProperty.FieldName = value.Name.Alias.ToCamel();
                entityProperty.PropertyName = value.Name.Alias.ToCapit();
                entityProperty.Description = value.Description;
                entityProperty.DefaultValue = ConvertDefaultValue(value);
                list.Add(entityProperty);
            }
            context.Put("EntityPropertyList", list);
            context.Put("IncrementList", value_Renamed);
        }

        private string ConvertDefaultValue(ColumnInfo columnInfo)
        {
            string empty = string.Empty;
            switch (columnInfo.NetType.Alias.ToLower())
            {
                case "string":
                    return string.Format("\"{0}\"", columnInfo.DefaultValue.Trim('\''));
                case "bool":
                    return columnInfo.DefaultValue != "1" ? "false" : "true";
                case "byte":
                case "single":
                case "int":
                case "int16":
                case "int64":
                case "short":
                case "long":
                case "decimal":
                case "double":
                case "float":
                    return columnInfo.DefaultValue != string.Empty ? columnInfo.DefaultValue : "0";
                case "byte[]":
                    return string.Format("System.Text.Encoding.Default.GetBytes(\"{0}\")", "0x01");
                case "datetime":
                    return "System.DateTime.Now";
                case "guid":
                    return "System.Guid.NewGuid()";
                default:
                    return string.Format("\"{0}\"", columnInfo.DefaultValue.Trim('\''));
            }
        }
    }
}
